package com.ffcc.fitness.websocket.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.ffcc.fitness.websocket.pojo.Message;
import com.ffcc.fitness.websocket.service.ChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Spring WebSocket聊天处理器
 */
@Component
public class SpringChatWebSocketHandler extends TextWebSocketHandler {
    
    // 存储用户连接
    private static final Map<Long, WebSocketSession> USER_SESSIONS = new ConcurrentHashMap<>();
      @Autowired
    private ChatService chatService;
    
    private final ObjectMapper objectMapper;
    
    // 构造函数中配置ObjectMapper
    public SpringChatWebSocketHandler() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.registerModule(new JavaTimeModule());
        this.objectMapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }    @Override
    public void afterConnectionEstablished(@NonNull WebSocketSession session) throws Exception {
        System.out.println("=== Spring WebSocket聊天连接建立 ===");
        System.out.println("Session ID: " + session.getId());
        System.out.println("Request URI: " + session.getUri());
        
        // 从URI中提取用户ID和token
        URI uri = session.getUri();
        if (uri == null) {
            System.err.println("无法获取请求URI");
            session.close(CloseStatus.BAD_DATA);
            return;
        }
        
        String path = uri.getPath();
        String query = uri.getQuery();
        
        System.out.println("Path: " + path);
        System.out.println("Query: " + query);
        
        // 提取用户ID (从路径 /websocket/chat/{userId} 中提取)
        String[] pathParts = path.split("/");
        if (pathParts.length < 4) {
            System.err.println("无效的WebSocket路径: " + path);
            session.close(CloseStatus.BAD_DATA);
            return;
        }
        
        Long userId;
        try {
            userId = Long.valueOf(pathParts[3]);
        } catch (NumberFormatException e) {
            System.err.println("无效的用户ID: " + pathParts[3]);
            session.close(CloseStatus.BAD_DATA);
            return;
        }
          // 提取token（暂时跳过验证）
        String token = null;
        if (query != null) {
            String[] queryParams = query.split("&");
            for (String param : queryParams) {
                if (param.startsWith("token=")) {
                    token = param.substring(6);
                    break;
                }
            }
        }
        
        System.out.println("Token: " + (token != null ? token.substring(0, Math.min(token.length(), 10)) + "..." : "null"));
        
        // 暂时跳过token验证，直接建立连接
        System.out.println("跳过token验证，直接建立连接...");
          // 将用户ID存储到session属性中
        session.getAttributes().put("userId", userId);
        USER_SESSIONS.put(userId, session);
        
        System.out.println("=== 用户 " + userId + " 连接Spring WebSocket聊天成功 ===");
        System.out.println("当前在线用户数: " + USER_SESSIONS.size());
        System.out.println("当前在线用户ID列表: " + USER_SESSIONS.keySet());
        
        // 发送连接成功消息
        Map<String, Object> connectMsg = Map.of(
            "type", "connect",
            "status", "success",
            "message", "连接成功"
        );
        String jsonMsg = objectMapper.writeValueAsString(connectMsg);
        session.sendMessage(new TextMessage(jsonMsg));
    }
      @Override
    public void handleMessage(@NonNull WebSocketSession session, @NonNull WebSocketMessage<?> message) throws Exception {
        Long userId = (Long) session.getAttributes().get("userId");
        
        if (message instanceof TextMessage) {
            String messageText = ((TextMessage) message).getPayload();
            System.out.println("收到用户 " + userId + " 的消息: " + messageText);
            
            try {
                // 解析消息
                @SuppressWarnings("unchecked")
                Map<String, Object> messageData = objectMapper.readValue(messageText, Map.class);
                Long toId = Long.valueOf(messageData.get("toId").toString());
                String content = messageData.get("content").toString();
                  // 保存消息到数据库
                Message msg = chatService.sendMessage(userId, toId, content);
                System.out.println("消息已保存到数据库: " + msg.getMessageId());
                
                // 调试：打印当前在线用户
                System.out.println("当前在线用户数: " + USER_SESSIONS.size());
                System.out.println("当前在线用户ID列表: " + USER_SESSIONS.keySet());
                System.out.println("目标用户ID: " + toId + ", 是否在线: " + USER_SESSIONS.containsKey(toId));
                
                // 发送消息给接收者
                WebSocketSession toSession = USER_SESSIONS.get(toId);
                if (toSession != null && toSession.isOpen()) {
                    System.out.println("找到接收者连接，准备发送消息");
                    String responseMessage = objectMapper.writeValueAsString(msg);
                    toSession.sendMessage(new TextMessage(responseMessage));
                    System.out.println("消息已发送给接收者: " + toId);
                } else {
                    System.out.println("接收者不在线或连接已关闭: " + toId);
                }
                
                // 确认消息发送给发送者
                Map<String, Object> ack = Map.of(
                    "type", "ack",
                    "messageId", msg.getMessageId(),
                    "status", "sent"
                );
                String ackMessage = objectMapper.writeValueAsString(ack);
                session.sendMessage(new TextMessage(ackMessage));
                System.out.println("发送确认消息给发送者: " + userId);
                
            } catch (Exception e) {
                System.err.println("处理消息失败: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
      @Override
    public void handleTransportError(@NonNull WebSocketSession session, @NonNull Throwable exception) throws Exception {
        Long userId = (Long) session.getAttributes().get("userId");
        System.err.println("用户 " + userId + " Spring WebSocket连接错误: " + exception.getMessage());
        exception.printStackTrace();
    }
      @Override
    public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull CloseStatus closeStatus) throws Exception {
        Long userId = (Long) session.getAttributes().get("userId");
        if (userId != null) {
            USER_SESSIONS.remove(userId);
            System.out.println("用户 " + userId + " 断开Spring WebSocket连接，状态: " + closeStatus);
        }
    }
    
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
    
    /**
     * 发送消息给指定用户
     */
    public static void sendMessageToUser(Long userId, String message) {
        WebSocketSession session = USER_SESSIONS.get(userId);
        if (session != null && session.isOpen()) {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
      /**
     * 检查用户是否在线
     */
    public static boolean isUserOnline(Long userId) {
        WebSocketSession session = USER_SESSIONS.get(userId);
        return session != null && session.isOpen();
    }
}
